package org.jheuristics.ga.operators;

import java.io.Serializable;

import org.jheuristics.ga.GAConfig;
import org.jheuristics.ga.GAStatus;
import org.jheuristics.ga.Population;

/**
 * TODO
 *
 * @author Marcell Manfrin, marcell@ourgrid.org, Jan 9, 2006
 */
public class ReproductionOperator extends AbstractReproductionOperator implements Serializable {
	private PopulationChooser fromPopChooser;
	private PopulationChooser toPopChooser;
	private boolean cleanAfterFromPop;
	private boolean cleanBeforeToPop;

	/**
	 * TODO
	 *
	 * @param rate
	 * @param selector
	 * @param reproductor
	 * @param fromPopChooser
	 * @param cleanAfterFromPop
	 * @param toPopChooser
	 * @param cleanBeforeToPop
	 */
	public ReproductionOperator(Rate rate, Selector selector, Reproductor reproductor, PopulationChooser fromPopChooser, boolean cleanAfterFromPop, PopulationChooser toPopChooser, boolean cleanBeforeToPop) {
		super(rate, selector, reproductor);
		if (null == fromPopChooser) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
		if (null == toPopChooser) {
			// TODO: ERROR MSG
			throw new NullPointerException();
		}
		this.fromPopChooser = fromPopChooser;
		this.toPopChooser = toPopChooser;
		this.cleanAfterFromPop = cleanAfterFromPop;
		this.cleanBeforeToPop = cleanBeforeToPop;
	}

	/**
	 * TODO
	 *
	 * @param status
	 * @param config
	 * @see org.jheuristics.ga.Operator#operate(org.jheuristics.ga.GAStatus, org.jheuristics.ga.GAConfig)
	 */
	public void operate(GAStatus status, GAConfig config) {
		Population fromPop = fromPopChooser.choose(status, config);
		Population toPop = toPopChooser.choose(status, config);
		Population reproductedIndividuals = reproduce(fromPop, status, config);
		if (cleanAfterFromPop) {
			fromPop.clear();
		}
		if (cleanBeforeToPop) {
			toPop.clear();
		}
		toPop.addIndividuals(reproductedIndividuals);
	}

}
